package com.threeti.mecool.core.domain.model.plan.pojo;

import com.threeti.mecool.core.infrastructure.persistence.plan.TaskRepository;
import org.codehaus.jackson.annotate.JsonIgnore;
import org.codehaus.jackson.annotate.JsonManagedReference;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.persistence.*;
import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Configurable
@Entity
@Table(name = "DM_WF_TASK")
public class Task {
    private Long id;
    private Integer version;
    private Integer actionId;
    private String actionName;
    private Long dataTypeId;
    private String dataTypeName;
    private TaskAction action;
    private List<TaskItem> taskItems = new ArrayList<TaskItem>();
    private Date updatedAt;
    private Integer removed;
    private TaskRepository taskRepository;

    //<editor-fold desc="static find">
    public static Task findById(Long id) {
        if (id == null) {
            return null;
        } else {
            return taskRepository().findOne(id);
        }
    }

    public static Task findByDataTypeId(Long dataTypeId) {
        return taskRepository().findByDataTypeId(dataTypeId);
    }
    //</editor-fold>

    //<editor-fold desc="constructor">
    public Task() {
    }

    public Task(Integer actionId, Long dataTypeId) {
        this();
        this.actionId = actionId;
        this.dataTypeId = dataTypeId;
    }
    //</editor-fold>

    public TaskItem createItem(String itemName) {
        TaskItem taskItem = new TaskItem(itemName);
        taskItem.setTask(this);
        taskItems.add(taskItem);
        return taskItem;
    }

    public TaskItem createItem(String itemName, String type, String score, String comment) {
        TaskItem taskItem = new TaskItem(itemName, type, score, comment);
        taskItem.setTask(this);
        taskItems.add(taskItem);
        return taskItem;
    }

    @Transactional
    public void save() {
        updatedAt = new Date();
        taskRepository.saveAndFlush(this);
    }

    @Transactional
    public void remove() {
        removed = 1;
        save();
    }

    //<editor-fold desc="get/set">
    private static TaskRepository taskRepository() {
        return new Task().taskRepository;
    }

    @Resource
    public void setTaskRepository(TaskRepository taskRepository) {
        this.taskRepository = taskRepository;
    }

    @Id
    @GeneratedValue
    public Long getId() {
        return id;
    }

    @Version
    public Integer getVersion() {
        return version;
    }

    public Integer getActionId() {
        return actionId;
    }

    @Transient
    public String getActionName() {
        if (actionName == null && actionId != null) {
            if (action == null) {
                action = TaskAction.from(actionId);
            }
            actionName = action.getText();
        }
        return actionName;
    }

    @NotNull
    public Long getDataTypeId() {
        return dataTypeId;
    }

    @Transient
    public String getDataTypeName() {
        if (dataTypeName == null && dataTypeId != null) {
            TaskActionDataType taskActionDataType = TaskActionDataType.findById(dataTypeId);
            dataTypeName = taskActionDataType.getName();
        }
        return dataTypeName;
    }

    @JsonIgnore
    @Transient
    public String getTaskName(){
    	StringBuffer sb=new StringBuffer();

    	sb.append(getActionName());
    	sb.append("-");
    	sb.append(getDataTypeName());

    	return sb.toString();
    }

    @JsonIgnore
    @Transient
    public TaskAction getAction() {
        if (action == null) {
            action = TaskAction.from(actionId);
        }
        return action;
    }

    @OneToMany(mappedBy = "task", cascade = CascadeType.ALL, orphanRemoval = true)
    @JsonManagedReference
    public List<TaskItem> getTaskItems() {
        return taskItems;
    }

    @Temporal(TemporalType.TIMESTAMP)
    @JsonIgnore
    public Date getUpdatedAt() {
        return updatedAt;
    }

    @JsonIgnore
    public Integer getRemoved() {
        return removed;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public void setVersion(Integer version) {
        this.version = version;
    }

    public void setActionId(Integer actionId) {
        this.actionId = actionId;
    }

    public void setActionName(String actionName) {
        this.actionName = actionName;
    }

    public void setDataTypeId(Long dataTypeId) {
        this.dataTypeId = dataTypeId;
    }

    void setDataTypeName(String dataTypeName) {
        this.dataTypeName = dataTypeName;
    }

    public void setAction(TaskAction val) {
        action = val;
        actionId = action.getId();
        actionName = action.getText();
    }

    public void setTaskItems(List<TaskItem> taskItems) {
        this.taskItems = taskItems;
    }

    public void setUpdatedAt(Date updatedAt) {
        this.updatedAt = updatedAt;
    }

    public void setRemoved(Integer removed) {
        this.removed = removed;
    }
//</editor-fold>

}
